/* components */
import QualificationBaseDialog from '@src/modules/setting/messageChannel/components/qualification/dialog/base'
/* hooks */
import { useDialog } from '@hooks/useDialog'
/* vue */
import { defineComponent, PropType } from 'vue'
/* model */
import { 
  BusinessLicenseTypeCNNEnum,
  BusinessLicenseTypeEnum,
  CreateQualificationRequestKeysEnum,
  DocumentTypeCNNEnum,
  DocumentTypeEnum,
  SMSQualificationFormStepEnum
} from '@src/modules/setting/messageChannel/components/qualification/model/enum'
import { 
  SMSQualificationCompanyFields, 
  SMSQualificationPersonFields, 
  SMSQualificationOtherFields 
} from '@src/modules/setting/messageChannel/components/qualification/model/fields'
/* css */
import '@src/modules/setting/messageChannel/components/qualification/dialog/form.scss'
/* util */
import { cloneDeep, isEmpty, isFalsy, isNotEmpty } from 'pub-bbx-utils'
import * as FormUtil from '@src/component/form/util'
import { FieldTypeMappingEnum } from '@model/enum/FieldMappingEnum'
import Field from '@model/entity/Field'
import { isNotArray } from '@src/util/type'
import { SaveQualificationRequest } from '@src/modules/setting/messageChannel/components/qualification/model/type'
import { findComponentsDownward } from '@src/util/assist'
import { convertQualificationAttachment, convertQualificationAttachments } from '@src/modules/setting/messageChannel/components/qualification/util'

enum QualificationBaseDialogEventEnum {
  NEXT_STEP = 'nextStep',
  DONE = 'done'
}

export default defineComponent({
  name: 'QualificationForm',
  props: {
    step: {
      type: String as PropType<SMSQualificationFormStepEnum>,
      default: SMSQualificationFormStepEnum.COMPANY
    }
  },
  data() {
    return {
      companyForm: {},
      personForm: {},
      otherForm: {},
      isEffectiveEndTimeLongTerm: false,
      effectiveEndTimeLongTermTime: '2999-12-31'
    }
  },
  computed: {
    companyFormComponent(): Record<string, any> {
      return this.$refs.CompanyForm as Record<string, any>
    },
    personFormComponent(): Record<string, any> {
      return this.$refs.PersonForm as Record<string, any>
    },
    otherFormComponent(): Record<string, any> {
      return this.$refs.OtherForm as Record<string, any>
    },
    allFields(): Field[] {
      return [
        ...SMSQualificationCompanyFields as Field[],
        ...SMSQualificationPersonFields as Field[],
        ...SMSQualificationOtherFields as Field[]
      ]
    },
    imageDisplayFields() {
      // 图片字段
      // @ts-ignore
      return this.allFields.filter((field: Field) => {
        const formTypes = [
          FieldTypeMappingEnum.ImageDisplay,
          FieldTypeMappingEnum.Attachment
        ]
        return formTypes.includes(field.formType as FieldTypeMappingEnum)
      })
    },
    imageDisplayFieldNameMap(): Record<string, Field> {
      // @ts-ignore
      return this.imageDisplayFields.reduce((acc: Record<string, Field>, field: Field) => {
        acc[field.fieldName] = field
        return acc
      }, {})
    }
  },
  methods: {
    initForm(value?: Record<string, any>) {
      
      let newValue = cloneDeep(value || {})

      // 营业证件类型字段处理
      const businessLicenseType = newValue.businessLicenseType as unknown as BusinessLicenseTypeEnum
      const newBusinessLicenseType = BusinessLicenseTypeCNNEnum[businessLicenseType]
      newValue.businessLicenseType = newBusinessLicenseType
      
      // 图片字段处理
      const imageDisplayFieldNameMap = this.imageDisplayFieldNameMap
      for (const fieldName in imageDisplayFieldNameMap) {
        
        const field = imageDisplayFieldNameMap[fieldName]
        // @ts-ignore
        const fieldValue = newValue[fieldName]
        
        if (isFalsy(fieldValue)) {
          continue
        }
        
        const limit = Number(field?.setting?.limit)
        const isMulti = limit > 1
        
        if (isFalsy(isMulti)) {
          const newFieldValue = convertQualificationAttachment(fieldValue)
          newValue[fieldName] = [newFieldValue]
        } else {
          const newFieldValue = convertQualificationAttachments(fieldValue || [])
          newValue[fieldName] = newFieldValue
        }
        
      }
      
      let companyForm: Record<string, any> = {}
      for (const field of SMSQualificationCompanyFields) {
        const fieldName = field.fieldName
        companyForm[fieldName] = newValue[fieldName]
      }
      
      let personForm: Record<string, any> = {}
      for (const field of SMSQualificationPersonFields) {
        const fieldName = field.fieldName
        personForm[fieldName] = newValue[fieldName]
      }
      
      let otherForm: Record<string, any> = {}
      for (const field of SMSQualificationOtherFields) {
        const fieldName = field.fieldName
        otherForm[fieldName] = newValue[fieldName]
      }
      
      this.companyForm = FormUtil.initialize(SMSQualificationCompanyFields, companyForm)
      this.personForm = FormUtil.initialize(SMSQualificationPersonFields, personForm)
      this.otherForm = FormUtil.initialize(SMSQualificationOtherFields, otherForm)
      
      setTimeout(() => {
        this.removeFormItemValidate()
      })
      
    },
    buildForm(): SaveQualificationRequest {
      
      let form: SaveQualificationRequest = this.mergeForm() as SaveQualificationRequest
      
      // 营业证件类型字段处理
      const businessLicenseType = form.businessLicenseType as unknown as string
      const newBusinessLicenseType = this.findBusinessLicenseTypeValue(businessLicenseType)
      form.businessLicenseType = newBusinessLicenseType
      
      // 图片字段
      const imageDisplayFieldNameMap = this.imageDisplayFieldNameMap
      for (const fieldName in imageDisplayFieldNameMap) {
        
        const field = imageDisplayFieldNameMap[fieldName]
        // @ts-ignore
        const value = form[fieldName] as Record<string, any>[]
        
        if (isFalsy(value) || isNotArray(value) || isEmpty(value)) {
          // @ts-ignore
          form[fieldName] = null
          continue
        }
        
        const limit = Number(field?.setting?.limit)
        const isMulti = limit > 1
        
        if (isMulti) {
          const newValue = value.map((item: Record<string, any>) => item.id)
          // @ts-ignore
          form[fieldName] = newValue
        } else {
          // @ts-ignore
          form[fieldName] = value[0]?.id
        }
        
      }
      
      const effectiveEndTime = form.effectiveEndTime
      if (effectiveEndTime === this.effectiveEndTimeLongTermTime) {
        this.isEffectiveEndTimeLongTerm = true
      }

      return form
      
    },
    mergeForm(): Record<string, any> {
      
      let companyForm = cloneDeep(this.companyForm)
      let personForm = cloneDeep(this.personForm)
      let otherForm = cloneDeep(this.otherForm)
      
      let newCompanyForm = {}
      SMSQualificationCompanyFields.forEach((field) => {
        const fieldName = field.fieldName
        // @ts-ignore
        newCompanyForm[fieldName] = companyForm[fieldName]
      })
      
      let newPersonForm = {}
      SMSQualificationPersonFields.forEach((field) => {
        const fieldName = field.fieldName
        // @ts-ignore
        newPersonForm[fieldName] = personForm[fieldName]
      })
      
      let newOtherForm = {}
      SMSQualificationOtherFields.forEach((field) => {
        const fieldName = field.fieldName
        // @ts-ignore
        newOtherForm[fieldName] = otherForm[fieldName]
      })

      return {
        ...newCompanyForm,
        ...newPersonForm,
        ...newOtherForm,
        smsAutograph: 'xxx'
      }
      
    },
    findBusinessLicenseTypeValue(currentBusinessLicenseType: string): BusinessLicenseTypeEnum {
      for (const BusinessLicenseTypeCNNEnumKey in BusinessLicenseTypeCNNEnum) {
        const value = BusinessLicenseTypeCNNEnum[BusinessLicenseTypeCNNEnumKey as unknown as keyof typeof BusinessLicenseTypeCNNEnum]
        if (value === currentBusinessLicenseType) {
          return Number(BusinessLicenseTypeCNNEnumKey) as unknown as BusinessLicenseTypeEnum
        }
      }
      throw new Error('未找到对应的营业证件类型')
    },
    findDocumentTypeValue(currentDocumentType: string): DocumentTypeEnum {
      for (const DocumentTypeCNNEnumKey in DocumentTypeCNNEnum) {
        const value = DocumentTypeCNNEnum[DocumentTypeCNNEnumKey as unknown as keyof typeof DocumentTypeCNNEnum]
        if (value === currentDocumentType) {
          return Number(DocumentTypeCNNEnumKey) as unknown as DocumentTypeEnum
        }
      }
      throw new Error('未找到对应的证件类型')
    },
    removeFormItemValidate() {
      
      const formItemComponents = findComponentsDownward(this, 'form-item')
      
      if (isNotEmpty(formItemComponents)) {
        formItemComponents.forEach((formItemComponent: Record<string, any>) => {
          formItemComponent.resetValidationStatus()
        })
      }
      
    },
    async nextStepHandler() {
      // 企业信息
      if (this.step === SMSQualificationFormStepEnum.COMPANY) {
        
        const valid = await this.validateCompanyForm()
        if (isFalsy(valid)) {
          throw new Error('企业信息校验失败')
        }
        // 下一步
        return SMSQualificationFormStepEnum.PERSON
      }
      
      // 个人信息
      if (this.step === SMSQualificationFormStepEnum.PERSON) {
        
        const valid = await this.validatePersonForm()
        if (isFalsy(valid)) {
          throw new Error('个人信息校验失败')
        }
        
        // 下一步
        return SMSQualificationFormStepEnum.OTHER
      }
      
      // 其他信息
      if (this.step === SMSQualificationFormStepEnum.OTHER) {
        
        const valid = await this.validateOtherForm()
        if (isFalsy(valid)) {
          throw new Error('其他信息校验失败')
        }
        
        return true
      }
    },
    async prevStepHandler() {
      
      if (this.step === SMSQualificationFormStepEnum.PERSON) {
        return SMSQualificationFormStepEnum.COMPANY
      }
      
      if (this.step === SMSQualificationFormStepEnum.OTHER) {
        return SMSQualificationFormStepEnum.PERSON
      }

      return false
      
    },
    validateCompanyForm() {
      return this.companyFormComponent.validate()
    },
    validatePersonForm() {
      return this.personFormComponent.validate()
    },
    validateOtherForm() {
      return this.otherFormComponent.validate()
    },
    onCompanyFormChange(data: Record<string, any>) {
      
      if (isFalsy(data)) {
        console.error('企业信息更新数据为空')
        return
      }
      
      const { field, newValue } = data
      const fieldName = field?.fieldName
      if (isFalsy(fieldName)) {
        console.error('企业信息更新数据字段名为空')
        return
      }

      this.$set(this.companyForm, fieldName, newValue)
      
    },
    onPersonFormChange(data: Record<string, any>) {
      
      if (isFalsy(data)) {
        console.error('个人信息更新数据为空')
        return
      }

      const { field, newValue } = data
      const fieldName = field?.fieldName
      if (isFalsy(fieldName)) {
        console.error('个人信息更新数据字段名为空')
        return
      }
      
      this.$set(this.personForm, fieldName, newValue)
      
    },
    onOtherFormChange(data: Record<string, any>) {
        
      if (isFalsy(data)) {
        console.error('其他信息更新数据为空')
        return
      }
      
      const { field, newValue } = data
      const fieldName = field?.fieldName
      if (isFalsy(fieldName)) {
        console.error('其他信息更新数据字段名为空')
        return
      }
      
      this.$set(this.otherForm, fieldName, newValue)
      
    },
    onEffectiveEndTimeChange(value: string) {
      this.$set(this.companyForm, CreateQualificationRequestKeysEnum.EffectiveEndTime, value)
    },
    onEffectiveEndTimeLongTermChange(value: boolean) {
      
      this.isEffectiveEndTimeLongTerm = value
      
      if (value) {
        this.$set(this.companyForm, CreateQualificationRequestKeysEnum.EffectiveEndTime, this.effectiveEndTimeLongTermTime)
      }
      
    },
    renderStep() {
      switch (this.step) {
        case SMSQualificationFormStepEnum.COMPANY:
          return this.renderStepCompany()
        case SMSQualificationFormStepEnum.PERSON:
          return this.renderStepPerson()
        case SMSQualificationFormStepEnum.OTHER:
          return this.renderStepOther()
        default:
          throw new Error('未知的步骤')
      }
    },
    renderEffectiveEndTimeField({ field, value }: Record<string, any>) {
      return (
        <form-item 
          field={field}
          label={field.displayName} 
          class="bbx-form-cell-item"
        >
          
          <div slot="operation">
            <el-checkbox
              value={this.isEffectiveEndTimeLongTerm}
              onInput={this.onEffectiveEndTimeLongTermChange}
            >
              长期有效
            </el-checkbox>
          </div>
          
          <form-date 
            field={field}
            value={value}
            nativeDisabled={this.isEffectiveEndTimeLongTerm}
            onInput={this.onEffectiveEndTimeChange}
          >
          </form-date>
        </form-item>
      )
    },
    renderStepCompany() {
      return (
        <div class="qualification-form-company">
          <div class="qualification-form-title">
            1. 企业信息
          </div>
          <form-builder
            ref="CompanyForm"
            value={this.companyForm}
            fields={SMSQualificationCompanyFields}
            onUpdate={this.onCompanyFormChange}
            scopedSlots={{
              [CreateQualificationRequestKeysEnum.EffectiveEndTime]: this.renderEffectiveEndTimeField
            }}
          > 
          </form-builder>
        </div>
      )
    },
    renderStepPerson() {
      return (
        <div class="qualification-form-person">
          <div class="qualification-form-title">
            2. 责任人信息
          </div>
          <form-builder
            ref="PersonForm"
            value={this.personForm}
            fields={SMSQualificationPersonFields}
            onUpdate={this.onPersonFormChange}
          >
          </form-builder>
        </div>
      )
    },
    renderStepOther() {
      return (
        <div class="qualification-form-other">
          <div class="qualification-form-title">
            3. 其他材料 （选填）
          </div>
          <form-builder
            ref="OtherForm"
            value={this.otherForm}
            fields={SMSQualificationOtherFields}
            onUpdate={this.onOtherFormChange}
          >
          </form-builder>
        </div>
      )
    }
  },
  render() {
    return (
      <div class="qualification-form">
        { this.renderStep() }
      </div>
    )
  }
})